package api

import (
	"net/http"
	"strings"

	"alfred/database"
	"alfred/executor"
	"alfred/models"

	"github.com/gin-gonic/gin"
)

// APIResponse 统一的API响应结构
type APIResponse struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Data    any    `json:"data,omitempty"`
}

// NewSuccessResponse 创建成功响应
func NewSuccessResponse(data any) APIResponse {
	return APIResponse{
		Code:    0,
		Message: "success",
		Data:    data,
	}
}

// NewCreatedResponse 创建资源创建成功响应
func NewCreatedResponse(data any) APIResponse {
	return APIResponse{
		Code:    0,
		Message: "created successfully",
		Data:    data,
	}
}

// NewErrorResponse 创建错误响应
func NewErrorResponse(code int, message string) APIResponse {
	return APIResponse{
		Code:    code,
		Message: message,
	}
}

type Handler struct {
	db       *database.DB
	executor *executor.Executor
}

// NewHandler 创建新的API处理器
func NewHandler(db *database.DB, executor *executor.Executor) *Handler {
	return &Handler{
		db:       db,
		executor: executor,
	}
}

// RequireJSONContentType 中间件：验证Content-Type为application/json
func RequireJSONContentType() gin.HandlerFunc {
	return func(c *gin.Context) {
		if c.Request.Method == "POST" || c.Request.Method == "PUT" {
			contentType := c.GetHeader("Content-Type")
			if contentType == "" || !strings.Contains(contentType, "application/json") {
				c.JSON(http.StatusUnsupportedMediaType, NewErrorResponse(415, "Content-Type must be application/json"))
				c.Abort()
				return
			}
		}
		c.Next()
	}
}

// Flow相关接口

// CreateFlow 创建Flow
func (h *Handler) CreateFlow(c *gin.Context) {
	var flow models.Flow
	if err := c.ShouldBindJSON(&flow); err != nil {
		c.JSON(http.StatusBadRequest, NewErrorResponse(400, err.Error()))
		return
	}

	// 验证必要字段
	if flow.Name == "" {
		c.JSON(http.StatusBadRequest, NewErrorResponse(400, "name is required"))
		return
	}
	if flow.Branch == "" {
		c.JSON(http.StatusBadRequest, NewErrorResponse(400, "branch is required"))
		return
	}
	if flow.RepoURL == "" {
		c.JSON(http.StatusBadRequest, NewErrorResponse(400, "repo_url is required"))
		return
	}

	if err := h.db.CreateFlow(&flow); err != nil {
		c.JSON(http.StatusInternalServerError, NewErrorResponse(500, err.Error()))
		return
	}

	c.JSON(http.StatusCreated, NewCreatedResponse(flow))
}

// GetFlow 获取Flow
func (h *Handler) GetFlow(c *gin.Context) {
	id := c.Param("id")
	flow, err := h.db.GetFlow(id)
	if err != nil {
		c.JSON(http.StatusNotFound, NewErrorResponse(404, "Flow not found"))
		return
	}

	c.JSON(http.StatusOK, NewSuccessResponse(flow))
}

// ListFlows 获取所有Flow
func (h *Handler) ListFlows(c *gin.Context) {
	flows, err := h.db.ListFlows()
	if err != nil {
		c.JSON(http.StatusInternalServerError, NewErrorResponse(500, err.Error()))
		return
	}

	c.JSON(http.StatusOK, NewSuccessResponse(flows))
}

// UpdateFlow 更新Flow
func (h *Handler) UpdateFlow(c *gin.Context) {
	id := c.Param("id")
	var flow models.Flow
	if err := c.ShouldBindJSON(&flow); err != nil {
		c.JSON(http.StatusBadRequest, NewErrorResponse(400, err.Error()))
		return
	}

	flow.ID = id
	if err := h.db.UpdateFlow(&flow); err != nil {
		c.JSON(http.StatusInternalServerError, NewErrorResponse(500, err.Error()))
		return
	}

	c.JSON(http.StatusOK, NewSuccessResponse(flow))
}

// DeleteFlow 删除Flow
func (h *Handler) DeleteFlow(c *gin.Context) {
	id := c.Param("id")
	if err := h.db.DeleteFlow(id); err != nil {
		c.JSON(http.StatusInternalServerError, NewErrorResponse(500, err.Error()))
		return
	}

	c.JSON(http.StatusOK, NewSuccessResponse(gin.H{"message": "Flow deleted successfully"}))
}

// Node相关接口

// CreateNode 创建Node
func (h *Handler) CreateNode(c *gin.Context) {
	var node models.Node
	if err := c.ShouldBindJSON(&node); err != nil {
		c.JSON(http.StatusBadRequest, NewErrorResponse(400, err.Error()))
		return
	}

	if err := h.db.CreateNode(&node); err != nil {
		c.JSON(http.StatusInternalServerError, NewErrorResponse(500, err.Error()))
		return
	}

	c.JSON(http.StatusCreated, NewCreatedResponse(node))
}

// GetNode 获取Node
func (h *Handler) GetNode(c *gin.Context) {
	id := c.Param("id")
	node, err := h.db.GetNode(id)
	if err != nil {
		c.JSON(http.StatusNotFound, NewErrorResponse(404, "Node not found"))
		return
	}

	c.JSON(http.StatusOK, NewSuccessResponse(node))
}

// ListNodes 获取所有Node
func (h *Handler) ListNodes(c *gin.Context) {
	flowID := c.Query("flow_id")
	if flowID != "" {
		nodes, err := h.db.GetNodesByFlowID(flowID)
		if err != nil {
			c.JSON(http.StatusInternalServerError, NewErrorResponse(500, err.Error()))
			return
		}
		c.JSON(http.StatusOK, NewSuccessResponse(nodes))
		return
	}

	nodes, err := h.db.ListNodes()
	if err != nil {
		c.JSON(http.StatusInternalServerError, NewErrorResponse(500, err.Error()))
		return
	}

	c.JSON(http.StatusOK, NewSuccessResponse(nodes))
}

// UpdateNode 更新Node
func (h *Handler) UpdateNode(c *gin.Context) {
	id := c.Param("id")
	var node models.Node
	if err := c.ShouldBindJSON(&node); err != nil {
		c.JSON(http.StatusBadRequest, NewErrorResponse(400, err.Error()))
		return
	}

	node.ID = id
	if err := h.db.UpdateNode(&node); err != nil {
		c.JSON(http.StatusInternalServerError, NewErrorResponse(500, err.Error()))
		return
	}

	c.JSON(http.StatusOK, NewSuccessResponse(node))
}

// DeleteNode 删除Node
func (h *Handler) DeleteNode(c *gin.Context) {
	id := c.Param("id")
	if err := h.db.DeleteNode(id); err != nil {
		c.JSON(http.StatusInternalServerError, NewErrorResponse(500, err.Error()))
		return
	}

	c.JSON(http.StatusOK, NewSuccessResponse(gin.H{"message": "Node deleted successfully"}))
}

// GetNodeScript 获取节点脚本
func (h *Handler) GetNodeScript(c *gin.Context) {
	nodeID := c.Param("id")
	
	// 获取节点的默认脚本Action
	action, err := h.db.GetNodeDefaultScript(nodeID)
	if err != nil {
		// 如果没有找到默认脚本，返回空脚本
		c.JSON(http.StatusOK, NewSuccessResponse(gin.H{
			"type":    "python3",
			"content": "",
		}))
		return
	}
	
	c.JSON(http.StatusOK, NewSuccessResponse(gin.H{
		"type":    action.Type,
		"content": action.Content,
	}))
}

// SaveNodeScript 保存节点脚本
func (h *Handler) SaveNodeScript(c *gin.Context) {
	nodeID := c.Param("id")
	
	var request struct {
		Type    string `json:"type" binding:"required"`
		Content string `json:"content"`
	}
	
	if err := c.ShouldBindJSON(&request); err != nil {
		c.JSON(http.StatusBadRequest, NewErrorResponse(400, err.Error()))
		return
	}
	
	// 验证脚本类型
	if request.Type != "python3" && request.Type != "shell" {
		c.JSON(http.StatusBadRequest, NewErrorResponse(400, "unsupported script type: "+request.Type))
		return
	}
	
	// 保存或更新节点的默认脚本
	if err := h.db.SaveNodeDefaultScript(nodeID, request.Type, request.Content); err != nil {
		c.JSON(http.StatusInternalServerError, NewErrorResponse(500, err.Error()))
		return
	}
	
	c.JSON(http.StatusOK, NewSuccessResponse(gin.H{"message": "Script saved successfully"}))
}

// Action相关接口

// CreateAction 创建Action
func (h *Handler) CreateAction(c *gin.Context) {
	var action models.Action
	if err := c.ShouldBindJSON(&action); err != nil {
		c.JSON(http.StatusBadRequest, NewErrorResponse(400, err.Error()))
		return
	}

	// 验证Action类型
	if action.Type != "shell" && action.Type != "python" {
		c.JSON(http.StatusBadRequest, NewErrorResponse(400, "unsupported action type: "+action.Type))
		return
	}

	if err := h.db.CreateAction(&action); err != nil {
		c.JSON(http.StatusInternalServerError, NewErrorResponse(500, err.Error()))
		return
	}

	c.JSON(http.StatusCreated, NewCreatedResponse(action))
}

// GetAction 获取Action
func (h *Handler) GetAction(c *gin.Context) {
	id := c.Param("id")
	action, err := h.db.GetAction(id)
	if err != nil {
		c.JSON(http.StatusNotFound, NewErrorResponse(404, "Action not found"))
		return
	}

	c.JSON(http.StatusOK, NewSuccessResponse(action))
}

// ListActions 获取所有Action
func (h *Handler) ListActions(c *gin.Context) {
	nodeID := c.Query("node_id")
	if nodeID != "" {
		actions, err := h.db.GetActionsByNodeID(nodeID)
		if err != nil {
			c.JSON(http.StatusInternalServerError, NewErrorResponse(500, err.Error()))
			return
		}
		c.JSON(http.StatusOK, NewSuccessResponse(actions))
		return
	}

	actions, err := h.db.ListActions()
	if err != nil {
		c.JSON(http.StatusInternalServerError, NewErrorResponse(500, err.Error()))
		return
	}

	c.JSON(http.StatusOK, NewSuccessResponse(actions))
}

// UpdateAction 更新Action
func (h *Handler) UpdateAction(c *gin.Context) {
	id := c.Param("id")
	var action models.Action
	if err := c.ShouldBindJSON(&action); err != nil {
		c.JSON(http.StatusBadRequest, NewErrorResponse(400, err.Error()))
		return
	}

	action.ID = id
	if err := h.db.UpdateAction(&action); err != nil {
		c.JSON(http.StatusInternalServerError, NewErrorResponse(500, err.Error()))
		return
	}

	c.JSON(http.StatusOK, NewSuccessResponse(action))
}

// DeleteAction 删除Action
func (h *Handler) DeleteAction(c *gin.Context) {
	id := c.Param("id")
	if err := h.db.DeleteAction(id); err != nil {
		c.JSON(http.StatusInternalServerError, NewErrorResponse(500, err.Error()))
		return
	}

	c.JSON(http.StatusOK, NewSuccessResponse(gin.H{"message": "Action deleted successfully"}))
}
